package com.byinsight.web.actions.util;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.byinsight.service.dto.Dimension;
import com.byinsight.web.actions.Constants;
import com.byinsight.web.actions.ErrorCode;

import eg.backend.base.PermissionType;

public class DimensionDefinitionParser extends BaseXMLParser{
	
	private class DimDefSAXHandler extends DefaultHandler {
		private Dimension curDim;
		
		@Override
		public void startDocument() throws SAXException {
			dimensions = new ArrayList<Dimension>();
		}
		
		@Override
		public void startElement(String namespaceURI, String localName,
				String qName, Attributes atts) throws SAXException {
			
			if ("node".equals(localName)) {
				String id = atts.getValue(Constants.DIM_ID);
				String name = atts.getValue(Constants.DIM_NAME);
				String permission = atts.getValue(Constants.DIM_PERMISSION);
				
				Dimension dim = null;
				if (null == curDim) {
					// It's the root dimension.
					curDim = new Dimension();
					rootDim = curDim;
					curDim.setPosition("0.");
					curDim.setChildPosition(0);
					curDim.setRootDimension(rootDim);
					dim = curDim;
				} else {
					dim = new Dimension();
					int insertPos = curDim.getChildPosition();
					dim.setPosition(curDim.getPosition() + insertPos + ".");
					dim.setChildPosition(0);
					dim.setRootDimension(rootDim);
					curDim.setChildPosition(++insertPos);
					dim.setParent(curDim);
					addChild(curDim, dim);
					curDim = dim;
				}				
				
				if (id != null) {
					dim.setEncodedKey(id);
				}
				dim.setName(name);
				PermissionType pt = DimensionHelper.stringToPermissionType(permission);
				dim.setPermission(pt);
				
				dimensions.add(dim);
			}			
		}
		
		@Override
		public void endElement(String uri, String localName, String name)
				throws SAXException {
			if (curDim != null && curDim.getParent() != null) {
				curDim = curDim.getParent();
			}
		}
		
		private void addChild(Dimension parent, Dimension child) {
			if (parent.getChildren() == null) {
				List<Dimension> children = new ArrayList<Dimension>();
				children.add(child);
				parent.setChildren(children);
			} else {
				parent.getChildren().add(child);
			}
		}
	}
	
	protected DefaultHandler getHandler() {
		return new DimDefSAXHandler();
	}
	
	protected ErrorCode getParseErrorCode() {
		return ErrorCode.DIMDEF_PARSE_ERROR;
	}
	
	public Dimension getRootDimension() {
		return rootDim;
	}
	
	public List<Dimension> getDimensions() {
		return dimensions;
	}
	
	private Dimension rootDim;
	private List<Dimension> dimensions;

}
